//
//  UIButton..swift
//  Documentation
//
//  Created by Toj on 7/28/23.
//

import Foundation

@available(iOS 15.0, tvOS 15.0, *)
extension UIButton {

    public struct Configuration : Hashable {

        public enum Size {

            case mini

            case small

            case medium

            case large

            /// Returns a Boolean value indicating whether two values are equal.
            ///
            /// Equality is the inverse of inequality. For any values `a` and `b`,
            /// `a == b` implies that `a != b` is `false`.
            ///
            /// - Parameters:
            ///   - lhs: A value to compare.
            ///   - rhs: Another value to compare.
            public static func == (a: UIButton.Configuration.Size, b: UIButton.Configuration.Size) -> Bool

            /// Hashes the essential components of this value by feeding them into the
            /// given hasher.
            ///
            /// Implement this method to conform to the `Hashable` protocol. The
            /// components used for hashing must be the same as the components compared
            /// in your type's `==` operator implementation. Call `hasher.combine(_:)`
            /// with each of these components.
            ///
            /// - Important: Never call `finalize()` on `hasher`. Doing so may become a
            ///   compile-time error in the future.
            ///
            /// - Parameter hasher: The hasher to use when combining the components
            ///   of this instance.
            public func hash(into hasher: inout Hasher)

            /// The hash value.
            ///
            /// Hash values are not guaranteed to be equal across different executions of
            /// your program. Do not save hash values to use during a future execution.
            ///
            /// - Important: `hashValue` is deprecated as a `Hashable` requirement. To
            ///   conform to `Hashable`, implement the `hash(into:)` requirement instead.
            public var hashValue: Int { get }
        }

        public enum TitleAlignment {

            /// Align title & subtitle automatically
            case automatic

            /// Align title & subtitle along their leading edges
            case leading

            /// Align title & subtitle to be centered with respect to each other
            case center

            /// Align title & subtitle along their trailing edges
            case trailing

            /// Returns a Boolean value indicating whether two values are equal.
            ///
            /// Equality is the inverse of inequality. For any values `a` and `b`,
            /// `a == b` implies that `a != b` is `false`.
            ///
            /// - Parameters:
            ///   - lhs: A value to compare.
            ///   - rhs: Another value to compare.
            public static func == (a: UIButton.Configuration.TitleAlignment, b: UIButton.Configuration.TitleAlignment) -> Bool

            /// Hashes the essential components of this value by feeding them into the
            /// given hasher.
            ///
            /// Implement this method to conform to the `Hashable` protocol. The
            /// components used for hashing must be the same as the components compared
            /// in your type's `==` operator implementation. Call `hasher.combine(_:)`
            /// with each of these components.
            ///
            /// - Important: Never call `finalize()` on `hasher`. Doing so may become a
            ///   compile-time error in the future.
            ///
            /// - Parameter hasher: The hasher to use when combining the components
            ///   of this instance.
            public func hash(into hasher: inout Hasher)

            /// The hash value.
            ///
            /// Hash values are not guaranteed to be equal across different executions of
            /// your program. Do not save hash values to use during a future execution.
            ///
            /// - Important: `hashValue` is deprecated as a `Hashable` requirement. To
            ///   conform to `Hashable`, implement the `hash(into:)` requirement instead.
            public var hashValue: Int { get }
        }

        public enum CornerStyle {

            /// The corner radius provided by the background style will be used as is, without adjusting for dynamic type
            case fixed

            /// The corner radius provided by the background style is adjusted based on dynamic type
            case dynamic

            /// Ignore the corner radius provided by the background style and substitute a small system defined corner radius.
            case small

            /// Ignore the corner radius provided by the background style and substitute a medium system defined corner radius.
            case medium

            /// Ignore the corner radius provided by the background style and substitute a large system defined corner radius.
            case large

            /// Ignore the corner radius provided by the background style and always set the corner radius to generate a capsule.
            case capsule

            /// Returns a Boolean value indicating whether two values are equal.
            ///
            /// Equality is the inverse of inequality. For any values `a` and `b`,
            /// `a == b` implies that `a != b` is `false`.
            ///
            /// - Parameters:
            ///   - lhs: A value to compare.
            ///   - rhs: Another value to compare.
            public static func == (a: UIButton.Configuration.CornerStyle, b: UIButton.Configuration.CornerStyle) -> Bool

            /// Hashes the essential components of this value by feeding them into the
            /// given hasher.
            ///
            /// Implement this method to conform to the `Hashable` protocol. The
            /// components used for hashing must be the same as the components compared
            /// in your type's `==` operator implementation. Call `hasher.combine(_:)`
            /// with each of these components.
            ///
            /// - Important: Never call `finalize()` on `hasher`. Doing so may become a
            ///   compile-time error in the future.
            ///
            /// - Parameter hasher: The hasher to use when combining the components
            ///   of this instance.
            public func hash(into hasher: inout Hasher)

            /// The hash value.
            ///
            /// Hash values are not guaranteed to be equal across different executions of
            /// your program. Do not save hash values to use during a future execution.
            ///
            /// - Important: `hashValue` is deprecated as a `Hashable` requirement. To
            ///   conform to `Hashable`, implement the `hash(into:)` requirement instead.
            public var hashValue: Int { get }
        }

        public enum MacIdiomStyle {

            /// Automatically select the style to use
            case automatic

            /// Always use a bordered style button
            case bordered

            /// Always use a borderless style button
            case borderless

            /// Always use a tinted, borderless style button
            case borderlessTinted

            /// Returns a Boolean value indicating whether two values are equal.
            ///
            /// Equality is the inverse of inequality. For any values `a` and `b`,
            /// `a == b` implies that `a != b` is `false`.
            ///
            /// - Parameters:
            ///   - lhs: A value to compare.
            ///   - rhs: Another value to compare.
            public static func == (a: UIButton.Configuration.MacIdiomStyle, b: UIButton.Configuration.MacIdiomStyle) -> Bool

            /// Hashes the essential components of this value by feeding them into the
            /// given hasher.
            ///
            /// Implement this method to conform to the `Hashable` protocol. The
            /// components used for hashing must be the same as the components compared
            /// in your type's `==` operator implementation. Call `hasher.combine(_:)`
            /// with each of these components.
            ///
            /// - Important: Never call `finalize()` on `hasher`. Doing so may become a
            ///   compile-time error in the future.
            ///
            /// - Parameter hasher: The hasher to use when combining the components
            ///   of this instance.
            public func hash(into hasher: inout Hasher)

            /// The hash value.
            ///
            /// Hash values are not guaranteed to be equal across different executions of
            /// your program. Do not save hash values to use during a future execution.
            ///
            /// - Important: `hashValue` is deprecated as a `Hashable` requirement. To
            ///   conform to `Hashable`, implement the `hash(into:)` requirement instead.
            public var hashValue: Int { get }
        }

        public static func plain() -> UIButton.Configuration

        public static func tinted() -> UIButton.Configuration

        public static func gray() -> UIButton.Configuration

        public static func filled() -> UIButton.Configuration

        public static func borderless() -> UIButton.Configuration

        public static func bordered() -> UIButton.Configuration

        public static func borderedTinted() -> UIButton.Configuration

        public static func borderedProminent() -> UIButton.Configuration

        /// Returns a copy of the configuration updated based on the given button, by applying the configuration's default values for that button's state to any properties that have not been customized.
        public func updated(for button: UIButton) -> UIButton.Configuration

        public var background: UIBackgroundConfiguration

        /// The corner style controls how background.cornerRadius is interpreted by the button. Defaults to `.dynamic`.
        public var cornerStyle: UIButton.Configuration.CornerStyle

        /// Determines the metrics and ideal size of the button. Clients may resize the button arbitrarily regardless of this value.
        public var buttonSize: UIButton.Configuration.Size

        /// Button style to use when running under the Mac idiom.
        public var macIdiomStyle: UIButton.Configuration.MacIdiomStyle

        /// The base color to use for foreground elements. This color may be modified before being passed to a transformer, and finally applied to specific elements. Setting nil will cede full control to the configuration to select a color appropriate to the style.
        public var baseForegroundColor: UIColor?

        /// The base color to use for background elements. This color may be modified before being passed to a transformer, and finally applied to specific elements. Setting nil will cede full control to the configuration to select a color appropriate to the style.
        public var baseBackgroundColor: UIColor?

        public var image: UIImage?

        public var imageColorTransformer: UIConfigurationColorTransformer?

        public var preferredSymbolConfigurationForImage: UIImage.SymbolConfiguration?

        /// Shows an activity indicator in place of an image. Its placement is controlled by the imagePlacement property.
        public var showsActivityIndicator: Bool

        public var activityIndicatorColorTransformer: UIConfigurationColorTransformer?

        public var title: String?

        public var attributedTitle: AttributedString?

        public var titleTextAttributesTransformer: UIConfigurationTextAttributesTransformer?

        public var subtitle: String?

        public var attributedSubtitle: AttributedString?

        public var subtitleTextAttributesTransformer: UIConfigurationTextAttributesTransformer?

        /// By default the button's content region is inset from its bounds based on the button's styling properties. The contentInsets are an additional inset applied afterwards.
        public var contentInsets: NSDirectionalEdgeInsets

        /// Restore the default content insets.
        public mutating func setDefaultContentInsets()

        /// Defaults to Leading, only single edge values (top/leading/bottom/trailing) are supported.
        public var imagePlacement: NSDirectionalRectEdge

        /// When a button has both image and text content, this value is the padding between the image and the text.
        public var imagePadding: CGFloat

        /// When a button has both a title & subtitle, this value is the padding between those titles.
        public var titlePadding: CGFloat

        /// The alignment to use for relative layout between title & subtitle.
        public var titleAlignment: UIButton.Configuration.TitleAlignment

        /// If the style should automatically update when the button is selected. Default varies by style. Disable to customize selection behavior.
        public var automaticallyUpdateForSelection: Bool

        /// Hashes the essential components of this value by feeding them into the
        /// given hasher.
        ///
        /// Implement this method to conform to the `Hashable` protocol. The
        /// components used for hashing must be the same as the components compared
        /// in your type's `==` operator implementation. Call `hasher.combine(_:)`
        /// with each of these components.
        ///
        /// - Important: Never call `finalize()` on `hasher`. Doing so may become a
        ///   compile-time error in the future.
        ///
        /// - Parameter hasher: The hasher to use when combining the components
        ///   of this instance.
        public func hash(into hasher: inout Hasher)

        /// Returns a Boolean value indicating whether two values are equal.
        ///
        /// Equality is the inverse of inequality. For any values `a` and `b`,
        /// `a == b` implies that `a != b` is `false`.
        ///
        /// - Parameters:
        ///   - lhs: A value to compare.
        ///   - rhs: Another value to compare.
        public static func == (a: UIButton.Configuration, b: UIButton.Configuration) -> Bool

        /// The hash value.
        ///
        /// Hash values are not guaranteed to be equal across different executions of
        /// your program. Do not save hash values to use during a future execution.
        ///
        /// - Important: `hashValue` is deprecated as a `Hashable` requirement. To
        ///   conform to `Hashable`, implement the `hash(into:)` requirement instead.
        public var hashValue: Int { get }
    }

    public convenience init(configuration: UIButton.Configuration, primaryAction: UIAction? = nil)

    public var configuration: UIButton.Configuration?
}


@available(iOS 15.0, tvOS 15.0, *)
extension UIButton.Configuration.Size : Equatable {
}

@available(iOS 15.0, tvOS 15.0, *)
extension UIButton.Configuration.Size : Hashable {
}

@available(iOS 15.0, tvOS 15.0, *)
extension UIButton.Configuration.TitleAlignment : Equatable {
}

@available(iOS 15.0, tvOS 15.0, *)
extension UIButton.Configuration.TitleAlignment : Hashable {
}

@available(iOS 15.0, tvOS 15.0, *)
extension UIButton.Configuration.CornerStyle : Equatable {
}

@available(iOS 15.0, tvOS 15.0, *)
extension UIButton.Configuration.CornerStyle : Hashable {
}

@available(iOS 15.0, tvOS 15.0, *)
extension UIButton.Configuration.MacIdiomStyle : Equatable {
}

@available(iOS 15.0, tvOS 15.0, *)
extension UIButton.Configuration.MacIdiomStyle : Hashable {
}
